/**
 * 计算函数, 第一个是首页的计算表单的参数，第二个是光标最后获取焦点的其他参数值的输入框，从0-4
 * 第三个参数，是否是输入触发（此种情况只校验Pw）
 */
function calculate(data, lastIndex, inputTrigger) {
  if (lastIndex == -1) {
    return generateErrorResult("请至少输入一个已知参数");
  }

  // 校验温度输入框
  if (!checkEnvTemperature(data.envTemperature)) {
    return generateErrorResult("温度数值必须是实数且小数最多两位");
  }

  // 校验压力输入框
  if (!checkEnvPressure(data.envPressure)) {
    return generateErrorResult("温压力数值必须是实数且小数最多三位");
  }

  const e1 = parseFloat(data.envTemperature);
  const e2 = parseFloat(data.envPressure);
  const p1 = parseFloat(data.param1);
  const p2 = parseFloat(data.param2);
  const p3 = parseFloat(data.param3);
  const p4 = parseFloat(data.param4);
  const p5 = parseFloat(data.param5);

  console.log("计算：", e1, e2, p1, p2, p3, p4, p5, "lastIndex", lastIndex);

  // 环境变量以及中间变量
  const Temperature = e1 + 273.15;
  const Pressure = e2 * 1000;
  const Pws = expFunction(
    -6096.938 / Temperature + 21.2409642 - 2.711193 * 0.01 * Temperature + 1.673952 * 0.00001 * Temperature * Temperature + 2.433502 * logFunction(Temperature)
  );

  if (lastIndex == 0) {
    // 已知相对湿度
    if (!isNumber(p1)) {
      return generateErrorResult("请输入正确的相对湿度值");
    }

    if (p1 > 100 || p1 < 0) {
      return generateErrorResult("相对湿度范围0-100");
    }
    
    return iKnowHumidity(Temperature, Pressure, Pws, p1);
  }

  if (lastIndex == 1) {
    // 已知露点
    if (!isNumber(p2)) {
      return generateErrorResult("请输入正确的露点值");
    }
    if (e1 < p2) {
      return generateErrorResult("温度值应大于等于露点值");
    }
    
    return iKnowMeasure_Td(Temperature, Pressure, Pws, p2);
  }

  if (lastIndex == 2) {
    // 已知体积百分比干
    if (!isNumber(p3)) {
      return generateErrorResult("请输入正确的体积百分比【干】");
    }
    if (!inputTrigger && p3 <= 0) {
      return generateErrorResult("体积百分比【干】必须为正数");
    }
    
    return iKnowVOL_dry(Temperature, Pressure, Pws, p3);
  }

  if (lastIndex == 3) {
    if (!isNumber(p4)) {
      return generateErrorResult("请输入正确的体积百分比【湿】");
    }

    if (!inputTrigger && (p4 > 100 || p4 <= 0)) {
      return generateErrorResult("体积百分比【湿】范围0-100");
    }

    return iKnowVOL_wet(Temperature, Pressure, Pws, p4);
  }

  if (lastIndex == 4) {
    if (!isNumber(p5)) {
      return generateErrorResult("请输入正确的绝对湿度");
    }
    if (!inputTrigger && p5 <= 0) {
      return generateErrorResult("绝对湿度必须为正数");
    }
    
    return iKnowMeasure_AH(Temperature, Pressure, Pws, p5);
  }
}


/**
 * 已知相对湿度求其他参数
 * @param {*} temperature 
 * @param {*} pressure 
 * @param {*} pws 
 * @param {*} humidity 
 */
function iKnowHumidity(temperature, pressure, pws, humidity) {
  const Pw = humidity * pws / 100;

  // 相对湿度超100
  if (humidity > 100){
    return generateErrorResult("相对湿度超过100", true);
  }

  // 水蒸气分压超过压力
  if (Pw > pressure || Pw > pws) {
    return generateErrorResult("水蒸气分压超过总压力", true);
  }

  // 露点
  let Measure_Td = 243.12 * logFunction(Pw / 611.2) / (17.62 - logFunction(Pw / 611.2));
  if (Measure_Td < 0) {
    Measure_Td = ((272.12 * logFunction(Pw / 611.2)) / (22.46 - logFunction(Pw / 611.2)));
  }

  // 露点值超温度
  if (Measure_Td > (temperature - 273.15)) {
    return generateErrorResult("露点值超过温度值", true);
  }

  // 体积百分比（干）
  const VOL_dry = 100 * Pw / (pressure - Pw);
  // 体积百分比（湿）
  const VOL_wet = 100 * Pw / (pressure);
  // 绝对湿度
  const Measure_AH = 2.16679 * Pw / temperature;

  return generateCalResult(humidity, Measure_Td, VOL_dry, VOL_wet, Measure_AH, Pw, pws, temperature);
}

/**
 * 已知露点求其他参数
 * @param {*} temperature 
 * @param {*} pressure 
 * @param {*} pws 
 * @param {*} measure_td 
 */
function iKnowMeasure_Td(temperature, pressure, pws, measure_td) {
  let Pw;
  if (measure_td >= 0) {
    Pw = 611.2 * expFunction(17.62 * measure_td / (measure_td + 243.12));
  } else {
    Pw = 611.2 * expFunction(22.46 * measure_td / (measure_td + 272.12));
  }
  
  // 相对湿度
  const Humidity = Pw * 100 / pws;
  if (Humidity > 100){
    return generateErrorResult("相对湿度超过100", true);
  }

  // 水蒸气分压超过压力
  if (Pw > pressure || Pw > pws) {
    return generateErrorResult("水蒸气分压超过总压力", true);
  }

  // 体积百分比（干）
  const VOL_dry = 100 * Pw / (pressure - Pw);
  // 体积百分比（湿）
  const VOL_wet = 100 * Pw / (pressure);
  // 绝对湿度
  const Measure_AH = 2.16679 * Pw / temperature;

  return generateCalResult(Humidity, measure_td, VOL_dry, VOL_wet, Measure_AH, Pw, pws, temperature);
}

/**
 * 已知体积百分比（干）求其他参数
 * @param {*} temperature 
 * @param {*} pressure 
 * @param {*} pws 
 * @param {*} vol_dry 
 */
function iKnowVOL_dry(temperature, pressure, pws, vol_dry) {
  let Pw = vol_dry * pressure / (vol_dry + 100);
  
  // 水蒸气分压超过压力
  if (Pw > pressure || Pw > pws) {
    return generateErrorResult("水蒸气分压超过总压力", true);
  }

  // 相对湿度
  const Humidity = Pw * 100 / pws;
  if (Humidity > 100){
    return generateErrorResult("相对湿度超过100", true);
  }
  
  // 体积百分比（湿）
  const VOL_wet = 100 * vol_dry / (100 + vol_dry);
  // 露点
  let measure_td = 243.12 * logFunction(Pw / 611.2) / (17.62 - logFunction(Pw / 611.2));
  if (measure_td < 0) {
    measure_td = ((272.12 * logFunction(Pw / 611.2)) / (22.46 - logFunction(Pw / 611.2)));
  }

  // 露点值超温度
  if (measure_td > (temperature - 273.15)) {
    return generateErrorResult("露点值超过温度值", true);
  }

  // 绝对湿度
  const Measure_AH = 2.16679 * Pw / temperature;
  return generateCalResult(Humidity, measure_td, vol_dry, VOL_wet, Measure_AH, Pw, pws, temperature);
}

/**
 * 已知体积百分比（湿）求其他参数
 * @param {*} temperature 
 * @param {*} pressure 
 * @param {*} pws 
 * @param {*} vol_wet 
 */
function iKnowVOL_wet(temperature, pressure, pws, vol_wet) {
  let Pw = vol_wet * pressure / 100;

  // 水蒸气分压超过压力
  if (Pw > pressure || Pw > pws) {
    return generateErrorResult("水蒸气分压超过总压力", true);
  }

  // 相对湿度
  const Humidity = Pw * 100 / pws;
  if (Humidity > 100){
    return generateErrorResult("相对湿度超过100", true);
  }

  // 体积百分比（干）
  const VOL_dry = vol_wet * pressure / (pressure - Pw);
  // 露点
  let measure_td = 243.12 * logFunction(Pw / 611.2) / (17.62 - logFunction(Pw / 611.2));
  if (measure_td < 0) {
    measure_td = ((272.12 * logFunction(Pw / 611.2)) / (22.46 - logFunction(Pw / 611.2)));
  }

  // 露点值超温度
  if (measure_td > (temperature - 273.15)) {
    return generateErrorResult("露点值超过温度值", true);
  }

  // 绝对湿度
  const Measure_AH = 2.16679 * Pw / temperature;
  return generateCalResult(Humidity, measure_td, VOL_dry, vol_wet, Measure_AH, Pw, pws, temperature);
}

/**
 * 已知绝对湿度求其他参数
 * @param {*} temperature 
 * @param {*} pressure 
 * @param {*} pws 
 * @param {*} measure_ah 
 */
function iKnowMeasure_AH(temperature, pressure, pws, measure_ah) {
  let Pw = measure_ah * temperature / 2.16679;

  // 水蒸气分压超过压力
  if (Pw > pressure || Pw > pws) {
    return generateErrorResult("水蒸气分压超过总压力", true);
  }

  // 相对湿度
  const Humidity = Pw * 100 / pws;
  if (Humidity > 100){
    return generateErrorResult("相对湿度超过100", true);
  }

  // 体积百分比（干）
  const VOL_dry = 100 * Pw / (pressure - Pw);
  // 体积百分比（湿）
  const VOL_wet = 100 * Pw / (pressure);
  // 露点
  let measure_td = 243.12 * logFunction(Pw / 611.2) / (17.62 - logFunction(Pw / 611.2));
  if (measure_td < 0) {
    measure_td = ((272.12 * logFunction(Pw / 611.2)) / (22.46 - logFunction(Pw / 611.2)));
  }

  // 露点值超温度
  if (measure_td > (temperature - 273.15)) {
    return generateErrorResult("露点值超过温度值", true);
  }

  return generateCalResult(Humidity, measure_td, VOL_dry, VOL_wet, measure_ah, Pw, pws, temperature);
}

/**
 * 校验温度输入参数
 * @param {*} temperature 
 */
function checkEnvTemperature(temperature) {
  const regex = /^([\+ \-]?(([1-9]\d*)|(0)))([.]\d{0,2})?$/;
  if (temperature != "") {
    if (!regex.test(temperature)) {
      return false;
    }
  }
  return true;
}

/**
 * 校验压力输入参数
 * @param {*} pressure 
 */
function checkEnvPressure(pressure) {
  const regex = /^([\+ \-]?(([1-9]\d*)|(0)))([.]\d{0,3})?$/;
  if (pressure != "") {
    if (!regex.test(pressure)) {
      return false;
    }
  }
  return true;
}

function isNumber(parseFloatRes) {
  const re = /^[+-]?((\d*[.](\d{0,})$)|(\d+$))/;
  if (parseFloatRes != "") {
    if (!re.test(parseFloatRes)) {
      return false;
    }
  }
  return true;
}

function generateErrorResult(msg, flag) {
  return {
    "success": false,
    "msg": msg,
    "pwFlag": flag
  };
}

function generateSuccessResult(data, flag) {
  return {
    "success": true,
    "data": data,
    "pwFlag": flag != undefined ? flag : false
  };
}

/**
 * 校验 Pw是否超限
 * @param {*} pressure 压力 
 * @param {*} paramValue 输入框的参数
 * @param {*} lastInsertIndex  最后聚焦的输入框索引
 */
function checkPwInvliad(temperature, pressure, pws, paramValue, lastInsertIndex) {
  let res = true;
  let Pw;
  switch (lastInsertIndex) {
    case 0:
      Pw = paramValue * pws / 100;
      break;
    case 1:
      if (paramValue >= 0) {
        Pw = 611.2 * expFunction(17.62 * paramValue / (paramValue + 243.12));
      } else {
        Pw = 611.2 * expFunction(22.46 * paramValue / (paramValue + 272.12));
      }
      break;
    case 2:
      Pw = paramValue * pressure / (paramValue + 100);
      break;
    case 3:
      Pw = paramValue * pressure / 100;
      break;
    case 4:
      Pw = paramValue * temperature / 2.16679;
      break;
    default:
      Pw = 1;
      pressure = 100;
      break;
  }
  if (Pw > pws) {
    res = false;
  }
  return res;
}

function generateCalResult(p1, p2, p3, p4, p5, pw, pws, temperature) {
  return {
    "success": true,
    "data": {
      "p1": p1.toString(),
      "p2": p2.toString(),
      "p3": p3.toString(),
      "p4": p4.toString(),
      "p5": p5.toString(),
      "pw": pw,
      "temperature": temperature - 273.15,
      "exceed1": pw > pws,
      "exceed2": p2 > (temperature - 273.15),
    }
  };
}

/**
 * e的x次幂
 */
function expFunction(x) {
  return Math.exp(x);
}

/**
 * 返回2的自然对数
 */
function logFunction(n) {
  return Math.log(n);
}

module.exports = {
  cal: calculate
}